﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using Innoapps.FileTransfer.Library;
using Innoapps.FileTransfer.Helpers;
using Innoapps.FileTransfer.Models;
using System.Linq;

namespace Innoapps.FileTransfer.Library.Tests.Adapters.Receive
{
    [TestClass]
    public class FILE
    {

        [TestMethod]
        public void Receive_Exists_NoTempPath()
        {
            // Generate file info for test file
            FileInfo file = new FileInfo(Path.GetTempFileName());

            // Create a new instance with new id, new transfer and transfer settings
            Instance instance = new Instance();
            instance.transfer = new Models.Transfer();
            instance.transfer.NextAction = "Innoapps.FileTransfer.Adapters.Receive.Receive";
            instance.transfer.Id = Guid.NewGuid();

            // Create new receive adapter with settings to receive generated file
            FileTransfer.Adapters.Receive.FILE receiveAdapter = new FileTransfer.Adapters.Receive.FILE();
            receiveAdapter.FolderPath = file.DirectoryName;
            receiveAdapter.FileName = file.Name;
            receiveAdapter.RetryCount = 1;
            receiveAdapter.RetryInterval = 1;
            receiveAdapter.TemporaryFolder = "";
            receiveAdapter.transfer = instance.transfer;

            // Attach file receive adapter to transfer
            instance.transfer.Receive = receiveAdapter;

            // Create the physiccal test file
            StreamWriter sw = file.CreateText();
            sw.Write(new string('A', 1024));
            sw.Flush();
            sw.Close();
            sw.Dispose();

            // Open the test file as a file stream, get its checksum and close the stream
            FileStream stream = File.Open(file.FullName, FileMode.Open);
            string originalChecksum = StreamHelper.GetChecksumBuffered(stream);
            stream.Close();
            stream.Dispose();

            // Execute the receive method for the transfer
            instance.transfer.Receive.Receive();



            // Get the checksum of the received file
            string resultChecksum = StreamHelper.GetChecksumBuffered(instance.transfer.Stream);

            // Check that the receive result was completed successfully
            ActionResult lastEvent = instance.transfer.ActionResults.Last();
            Assert.AreEqual("Complete", lastEvent.Result, lastEvent.Message);

            // Check that the checksums match
            Assert.AreEqual(originalChecksum, resultChecksum, "Checksum does not match");

            // Delete the test file
            file.Delete();

            

        }


        [TestMethod]
        public void Receive_Exists_TempPath()
        {
            // Generate file info for test file
            FileInfo file = new FileInfo(Path.GetTempFileName());

            // Create a new instance with new id, new transfer and transfer settings
            Instance instance = new Instance();
            instance.transfer = new Models.Transfer();
            instance.transfer.NextAction = "Innoapps.FileTransfer.Adapters.Receive.Receive";
            instance.transfer.Id = Guid.NewGuid();

            // Create new receive adapter with settings to receive generated file
            FileTransfer.Adapters.Receive.FILE receiveAdapter = new FileTransfer.Adapters.Receive.FILE();
            receiveAdapter.FolderPath = file.DirectoryName;
            receiveAdapter.FileName = file.Name;
            receiveAdapter.RetryCount = 1;
            receiveAdapter.RetryInterval = 1;
            receiveAdapter.TemporaryFolder = Path.GetTempPath();
            receiveAdapter.transfer = instance.transfer;

            // Attach file receive adapter to transfer
            instance.transfer.Receive = receiveAdapter;

            // Create the physiccal test file
            StreamWriter sw = file.CreateText();
            sw.Write(new string('A', 1024));
            sw.Flush();
            sw.Close();
            sw.Dispose();

            // Open the test file as a file stream, get its checksum and close the stream
            FileStream stream = File.Open(file.FullName, FileMode.Open);
            string originalChecksum = StreamHelper.GetChecksumBuffered(stream);
            stream.Close();
            stream.Dispose();

            // Execute the receive method for the transfer
            instance.transfer.Receive.Receive();

            

            // Get the checksum of the received file
            string resultChecksum = StreamHelper.GetChecksumBuffered(instance.transfer.Stream);

            // Check that the receive result was completed successfully
            ActionResult lastEvent = instance.transfer.ActionResults.Last();
            Assert.AreEqual("Complete", lastEvent.Result, lastEvent.Message);

            // Check that the checksums match
            Assert.AreEqual(originalChecksum, resultChecksum, "Checksum does not match");

            // Delete the test file
            File.Delete(Path.Combine(receiveAdapter.TemporaryFolder, instance.transfer.Id + ".tmp"));
        }


        [TestMethod]
        public void Delete_Exists_NoTempPath()
        {
            // Generate file info for test file
            FileInfo file = new FileInfo(Path.GetTempFileName());

            // Create a new instance with new id, new transfer and transfer settings
            Instance instance = new Instance();
            instance.transfer = new Models.Transfer();
            
            instance.transfer.NextAction = "Innoapps.FileTransfer.Adapters.Receive.Delete";
            instance.transfer.Id = Guid.NewGuid();

            // Create new receive adapter with settings to receive generated file
            FileTransfer.Adapters.Receive.FILE receiveAdapter = new FileTransfer.Adapters.Receive.FILE();
            receiveAdapter.FolderPath = file.DirectoryName;
            receiveAdapter.FileName = file.Name;
            receiveAdapter.RetryCount = 1;
            receiveAdapter.RetryInterval = 1;
            receiveAdapter.TemporaryFolder = "";
            receiveAdapter.DeleteAfterTransfer = true;
            receiveAdapter.transfer = instance.transfer;

            // Attach file receive adapter to transfer
            instance.transfer.Receive = receiveAdapter;

            // Create the physiccal test file
            StreamWriter sw = file.CreateText();
            sw.Write(new string('A', 1024));
            sw.Flush();
            sw.Close();
            sw.Dispose();


            // Execute the delete method for the transfer
            instance.transfer.Receive.Delete();

            // Check that the receive result was completed successfully
            ActionResult lastEvent = instance.transfer.ActionResults.Last();
            Assert.AreEqual("Complete", lastEvent.Result, lastEvent.Message);

            // Check that the file no longer exists
            Assert.AreEqual(false, file.Exists, "File still exists");



        }


        [TestMethod]
        public void Delete_Exists_TempPath()
        {


            // Create a new instance with new id, new transfer and transfer settings
            Instance instance = new Instance();
            instance.transfer = new Models.Transfer();
            
            instance.transfer.NextAction = "Innoapps.FileTransfer.Adapters.Receive.Delete";
            instance.transfer.Id = Guid.NewGuid();

            // Generate file info for test file
            FileInfo file = new FileInfo(Path.Combine(Path.GetTempPath(),instance.transfer.Id + ".tmp"));

            // Create new receive adapter with settings to receive generated file
            FileTransfer.Adapters.Receive.FILE receiveAdapter = new FileTransfer.Adapters.Receive.FILE();
            receiveAdapter.FolderPath = file.DirectoryName;
            receiveAdapter.FileName = file.Name;
            receiveAdapter.RetryCount = 1;
            receiveAdapter.RetryInterval = 1;
            receiveAdapter.TemporaryFolder = Path.GetTempPath();
            receiveAdapter.DeleteAfterTransfer = true;
            receiveAdapter.transfer = instance.transfer;

            // Attach file receive adapter to transfer
            instance.transfer.Receive = receiveAdapter;

            // Create the physiccal test file
            StreamWriter sw = file.CreateText();
            sw.Write(new string('A', 1024));
            sw.Flush();
            sw.Close();
            sw.Dispose();


            // Execute the delete method for the transfer
            instance.transfer.Receive.Delete();

            // Check that the receive result was completed successfully
            ActionResult lastEvent = instance.transfer.ActionResults.Last();
            Assert.AreEqual("Complete", lastEvent.Result, lastEvent.Message);

            // Check that the file no longer exists
            Assert.AreEqual(false, file.Exists, "File still exists");
        }


        [TestMethod]
        public void Delete_Exists_DoNotDelete()
        {
            // Generate file info for test file
            FileInfo file = new FileInfo(Path.GetTempFileName());

            // Create a new instance with new id, new transfer and transfer settings
            Instance instance = new Instance();
            instance.transfer = new Models.Transfer();
            
            instance.transfer.NextAction = "Innoapps.FileTransfer.Adapters.Receive.Delete";
            instance.transfer.Id = Guid.NewGuid();

            // Create new receive adapter with settings to receive generated file
            FileTransfer.Adapters.Receive.FILE receiveAdapter = new FileTransfer.Adapters.Receive.FILE();
            receiveAdapter.FolderPath = file.DirectoryName;
            receiveAdapter.FileName = file.Name;
            receiveAdapter.RetryCount = 1;
            receiveAdapter.RetryInterval = 1;
            receiveAdapter.TemporaryFolder = "";
            receiveAdapter.DeleteAfterTransfer = false;
            receiveAdapter.transfer = instance.transfer;

            // Attach file receive adapter to transfer
            instance.transfer.Receive = receiveAdapter;

            // Create the physiccal test file
            StreamWriter sw = file.CreateText();
            sw.Write(new string('A', 1024));
            sw.Flush();
            sw.Close();
            sw.Dispose();


            // Execute the delete method for the transfer
            instance.transfer.Receive.Delete();

            // Check that the receive result was completed successfully
            ActionResult lastEvent = instance.transfer.ActionResults.Last();
            Assert.AreEqual("Complete", lastEvent.Result, lastEvent.Message);

            // Check that the file no longer exists
            Assert.AreEqual(true, file.Exists, "File does not exists");

            file.Delete();

        }



    }
}
